package zdyu.users;

import zdyu.users.authentication.None;
import zdyu.users.database.JDBCWrapper;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class FirstFuckingSolution implements Requirements {

    JDBCWrapper jdbcWrapper = new JDBCWrapper(
            "mysql",
            "localhost",
            (short) 3306,
            "tedu",
            "root",
            "adgjl[]\\khfs/.,"
    );

    static final String
            tableName = "users",
            usernameField = "username",
            passwordField = "password";

    @Override
    public synchronized Status register(String username, String passphrase) {
        try {
            if (!(!isUserExists(username))) return Status.userAlreadyExists;
            setPassphrase(username, passphrase);
            return Status.ok;
        }
         catch (SQLException throwables) {
            return Status.systemError;
        }
    }

    @Override
    public Status login(String username, String passphrase) {
        try {
            boolean isSuccess = authenticate(username, passphrase);
            if (!isSuccess) return Status.authenticationFailure;
            return Status.ok;
        } catch (SQLException throwables) {
            return Status.systemError;
        }
    }

    @Override
    public synchronized Status changePassphrase(String username, String oldPassphrase, String newPassphrase) {
        try {
            if (!authenticate(username, oldPassphrase)) return Status.authenticationFailure;
            setPassphrase(username, newPassphrase);
            return Status.ok;
        } catch (SQLException throwables) {
            return Status.systemError;
        }
    }

    /**
     * 认证用户
     * @param username      用户名
     * @param passphrase    密码
     * @return              是否认证成功
     * @throws SQLException 系统错误
     */
    boolean authenticate(String username, String passphrase) throws SQLException {
        try (PreparedStatement preparedStatement = jdbcWrapper.getPreparedStatement(
                "SELECT `"+usernameField+"`, `"+passwordField+"` " +
                        "FROM `"+tableName+"` " +
                        "WHERE `"+usernameField+"` = ?",
                username
            ).orElseThrow(SQLException::new)
        ) {
            try (ResultSet resultSet = preparedStatement.executeQuery()) {
                if (!resultSet.next()) return false;
                return None.main(passphrase, resultSet.getObject(passwordField));
            }
        }
    }

    /**
     * @param username  用户名
     * @return          用户名是否已存在
     * @throws SQLException 系统错误
     */
    boolean isUserExists(String username) throws SQLException {
        try (PreparedStatement selectStatement = jdbcWrapper.getPreparedStatement(
                "SELECT `"+usernameField+"`" +
                        "FROM `"+tableName+"` " +
                        "WHERE `"+usernameField+"` = ?",
                username
        ).orElseThrow(SQLException::new)
        ) {
            try (ResultSet resultSet = selectStatement.executeQuery()) {
                return resultSet.next();
            }
        }
    }


    void setPassphrase(String username, String passphrase) throws SQLException {
        try (PreparedStatement insertStatement = jdbcWrapper.getPreparedStatement(
                "UPDATE `"+tableName+"` " +
                        "SET `"+passwordField+"` = ? " +
                        "WHERE `"+usernameField+"` = ?",
                passphrase, username
        ).orElseThrow(SQLException::new)
        ) {
            insertStatement.executeUpdate();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        jdbcWrapper.close();

        super.finalize();
    }
}
